package jgrouse.jgdoc.xslt;

import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

public class FastProcessor implements URIResolver
{
	private File m_inputFile;
	private File m_templateFile;
	private Map<String, String> m_options;
	private List<ProcessorParams> m_params;
	
	public static class ProcessorParams
	{
		private Map<String, String> m_privateOptions;
		private File m_outputFile;
		
		public ProcessorParams()
		{
		}

		public Map<String, String> getPrivateOptions()
		{
			return m_privateOptions;
		}

		public void setPrivateOptions(Map<String, String> pPrivateOptions)
		{
			m_privateOptions = pPrivateOptions;
		}

		public File getOutputFile()
		{
			return m_outputFile;
		}

		public void setOutputFile(File pOutputFile)
		{
			m_outputFile = pOutputFile;
		}
	}
	
	public FastProcessor()
	{
		
	}

	public File getInputFile()
	{
		return m_inputFile;
	}

	public void setInputFile(File pInputFile)
	{
		m_inputFile = pInputFile;
	}

	public File getTemplateFile()
	{
		return m_templateFile;
	}

	public void setTemplateFile(File pTemplateFile)
	{
		m_templateFile = pTemplateFile;
	}

	public Map<String, String> getOptions()
	{
		return m_options;
	}

	public void setOptions(Map<String, String> pOptions)
	{
		m_options = pOptions;
	}

	public List<ProcessorParams> getParams()
	{
		return m_params;
	}

	public void setParams(List<ProcessorParams> pParams)
	{
		m_params = pParams;
	}
	
	public void process() throws Exception
	{
		TransformerFactory tf = TransformerFactory.newInstance();
		Source src = new SAXSource();
		src.setSystemId(m_templateFile.getAbsolutePath());			
		tf.setURIResolver(this);
		Templates templates = tf.newTemplates(src);
		
		Transformer transformer = templates.newTransformer();
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.parse(m_inputFile);
		DOMSource source = new DOMSource(doc);
		for (ProcessorParams pp : m_params)
		{
			transformer.clearParameters();
			for (Map.Entry<String, String> entry : m_options.entrySet())
			{
				transformer.setParameter(entry.getKey(), entry.getValue());
			}
			for (Map.Entry<String, String> entry : pp.m_privateOptions.entrySet())
			{
				transformer.setParameter(entry.getKey(), entry.getValue());
			}
			File f = pp.m_outputFile.getParentFile();
			f.mkdirs();
			Result res = new StreamResult(pp.m_outputFile);
			transformer.transform(source, res);
		}
	}
	
	public static void main(String[] args)
	{
		FastProcessor fp = new FastProcessor();
		Map<String, String> commonParams = new HashMap<String, String>();
		commonParams.put("rootPath", "");
		commonParams.put("version", "0.55");
		commonParams.put("projectName", "jBoozePlusPlus Da!");
		commonParams.put("projectDesc", "jBooze is for every project!");
		commonParams.put("navSection", "logical");
		fp.setOptions(commonParams);
		fp.setTemplateFile(new File("./skins/noframes/xslt/detail.xslt"));
		fp.setInputFile(new File("api/jgrouse.xml"));
		List<ProcessorParams> list = new LinkedList<ProcessorParams>();
		fp.setParams(list);
		
		ProcessorParams pp = new ProcessorParams();
		pp.setOutputFile(new File("api/logical/MyClass/innerStruct.html"));
		Map<String, String> po = new HashMap<String, String>();
		po.put("trueRootPath", "../../");
		po.put("objectName", "MyClass.innerStruct");
		pp.setPrivateOptions(po);
		list.add(pp);


		
		
		long start = System.currentTimeMillis();
		try
		{
			fp.process();
		} catch (Exception e)
		{
			e.printStackTrace();
		}
		
		System.out.println("Processing of " + list.size() + " took " + (System.currentTimeMillis() - start));
		
		
	}

	public Source resolve(String pHref, String pBase)
			throws TransformerException
	{
		File ref = new File(m_templateFile.getAbsoluteFile().getParent(), pHref);
		Source src = new SAXSource();
		src.setSystemId(ref.getAbsolutePath());
		return src;
	}
	
}
